package com.tengju.user.infrastructure.schedule;

import com.tengju.user.application.login.UserAccountService;
import com.tengju.user.domain.model.Row;
import com.tengju.user.domain.model.alert.AlertEvent;
import com.tengju.user.domain.model.alert.AlertService;
import com.tengju.user.domain.model.login.UserType;
import com.tengju.user.domain.model.sign.StarChangeRecordRepository;
import com.tengju.user.domain.model.user.StarLevelEnum;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 登陆指标
 */
@Slf4j
@Component
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class UserStatisticsJob {

    private final UserAccountService userAccountService;
    private final AlertService alertService;
    private final UserInfoRepository userInfoRepository;
    private final StarChangeRecordRepository starChangeRecordRepository;

    @Value("${user.statistics.alert.url}")
    String alertUrl;

    @XxlJob("userStatisticsJob")
    public ReturnT<String> execute(String params) {

        try {

            //用户数
            int total = userAccountService.countTotal(UserType.USER);
            //总签约服务商数
            int totalSign = userInfoRepository.countByStarLevel(StarLevelEnum.serviceLevel());

            LocalDate today = LocalDate.now();
            LocalDateTime from = LocalDateTime.of(today.getYear(), today.getMonthValue(), today.getDayOfMonth() - 1, 0, 0);
            LocalDateTime to = LocalDateTime.of(today.getYear(), today.getMonthValue(), today.getDayOfMonth(), 0, 0);

            //昨日新增用户数
            int totalNew = userAccountService.countNew(UserType.USER, from, to);

            List<Row> signNew = starChangeRecordRepository.signNew(from, to);
            Map<Integer, Row> signNewMap = signNew.stream()
                    .collect(Collectors.toMap(row -> (Integer) row.getValue("starLevel"), Function.identity()));


            AlertEvent alertEvent = new AlertEvent("腾炬用户数统计：");
            alertEvent.addItem("总用户数",total);
            alertEvent.addItem("昨日新增用户数",totalNew);
            alertEvent.addItem("总签约服务商数",totalSign);
            alertEvent.addItem("昨日新增服务商1星",
                    Optional.ofNullable(signNewMap.get(StarLevelEnum.CITY_STAR_ONE.getCode()))
                            .map(row -> (Integer)row.getValue("num")).orElse(0));
            alertEvent.addItem("昨日新增服务商2星",
                    Optional.ofNullable(signNewMap.get(StarLevelEnum.CITY_STAR_TWO.getCode()))
                            .map(row -> (Integer)row.getValue("num")).orElse(0));
            alertEvent.addItem("昨日新增服务商3星",
                    Optional.ofNullable(signNewMap.get(StarLevelEnum.CITY_STAR_THREE.getCode()))
                            .map(row -> (Integer)row.getValue("num")).orElse(0));
            alertEvent.addItem("昨日新增服务商4星",
                    Optional.ofNullable(signNewMap.get(StarLevelEnum.CITY_STAR_FOUR.getCode()))
                            .map(row -> (Integer)row.getValue("num")).orElse(0));
            alertEvent.addItem("昨日新增EC",
                    Optional.ofNullable(signNewMap.get(StarLevelEnum.EC.getCode()))
                            .map(row -> (Integer)row.getValue("num")).orElse(0));
            alertEvent.addItem("昨日新增SEC",
                    Optional.ofNullable(signNewMap.get(StarLevelEnum.SEC.getCode()))
                            .map(row -> (Integer)row.getValue("num")).orElse(0));
            alertEvent.addItem("昨日新增EEC",
                    Optional.ofNullable(signNewMap.get(StarLevelEnum.EEC.getCode()))
                            .map(row -> (Integer)row.getValue("num")).orElse(0));
            alertService.dataNotice(alertEvent,alertUrl);
            log.info("飞书推送成功");

        } catch (Exception e) {
            log.error("统计用户数失败", e);
            return ReturnT.FAIL;
        }


        return ReturnT.SUCCESS;
    }




}
